package com.itheima.edu.info.manager.service;

import com.itheima.edu.info.manager.dao.TeacherDao;
import com.itheima.edu.info.manager.domain.Option;
import com.itheima.edu.info.manager.domain.Teacher;
import com.itheima.edu.info.manager.factory.TeacherFactory;

import java.io.*;
import java.net.Socket;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Properties;

public class TeacherService implements Runnable {
    //创建持久层对象
    private static TeacherDao dao = TeacherFactory.getTeacherDao();

    //服务端发送数据到客户端的方法(str)
    public void sendClientData(String str) {
        try {
            //创建一个字符缓冲输出流
            BufferedWriter bw = new BufferedWriter(new OutputStreamWriter(sk.getOutputStream()));
            //将服务端指定的数据str发送给客户端
            bw.write(str);
            //换行
            bw.newLine();
            //刷新流
            bw.flush();
            //终止字符缓冲输出流
            sk.shutdownOutput();
        } catch (IOException e) {
            System.out.println("sendClientData异常..............");
        } finally {
        }
    }


    //业务层登录功能实现
    public void login(String str) {
        //获取客户端发送的用户登录信息
        String name = str.split(",")[0];
        String password = str.split(",")[1];
        //使用标记位思想,默认登录失败
        boolean flag = false;
        //以集合的形式获取文件中老师的账户信息
        Properties prop = dao.selectAccounts();
        //判断账户信息是否存在有与用户登录的一致
        if (prop != null && prop.containsKey(name) && password.equals(prop.getProperty(name))) {
            flag = true;
        }
        //将登录结果按照指定格式发送给客户端
        sendClientData(flag + "");

    }

    //功能:判断参数id是否存在集合中
    public void isExists(String id) {
        //使用标记位思想,默认不存在
        boolean flag = false;
        //获取所有老师信息
        ArrayList<Teacher> teachers = dao.selectTeacher();
        //遍历集合,查找id相同的对象
        for (Teacher teacher : teachers) {
            if (teacher != null && id.equals(teacher.getSid())) {
                //找到了相同id的对象,返回true
                flag = true;
            }
        }
        sendClientData(flag + "");
    }

    //业务层添加老师的方法
    public void addTeacher(String stuStr) {
        //1. 指挥库管把学生对象添加进系统
        //2. 将库管添加的结果再传递给当前类方法的调用者(客服)
        //切割字符串,获取每一个学生对象的属性,并将其构造成一个对象
        String[] split = stuStr.split(",");
        Teacher tea = new Teacher(split[0], split[1], split[2], split[3]);
        //使用标记位思想
        boolean flag = false;
        //添加前老师数量
        int start = dao.selectTeacher().size();
        //调用库管添加老师对象
        dao.addTeacher(tea);
        //添加后老师数量
        int end = dao.selectTeacher().size();
        //判断是否添加成功
        if ((end - start) == 1) {
            flag = true;
        }
        //将添加的结果按照指定格式发送给客户端
        sendClientData(flag + "");
    }

    //业务层:查找所有老师信息
    public void selectTeacher() {
        String str = "";
        //使用标记位思想
        boolean flag = false;
        //通过dao获取集合
        ArrayList<Teacher> list = dao.selectTeacher();
        //对获取的集合进行处理
        if (list != null) {
            for (Teacher teacher : list) {
                if (teacher != null) {
                    flag = true;
                    break;
                }
            }
        }
        //对集合进行排序
        if (flag) {
            //使用函数式编程思想给集合排序
            Collections.sort(list, (tea1, tea2) -> {
                if (tea1 != null & tea2 != null) {
                    return tea1.getSid().compareTo(tea2.getSid());
                } else {
                    return 0;
                }
            });
            //拼接所有对象的字符串表示形式
            for (Teacher teacher : list) {
                str = str + "=" + teacher.toString();
            }
            str = str.substring(1);
            //将拼接的字符串发送给客户端
        }
        sendClientData(str);
    }


    //业务层的修改功能
    public void updateTeacher(String str) {
        Teacher tea = new Teacher(str.split(",")[0], str.split(",")[1], str.split(",")[2], str.split(",")[3]);
        //使用标记位思想
        boolean res = false;
        //获得修改的教师id
        String id = tea.getSid();
        //获得同一个id在集合中的索引值
        int index = byIdGetIndex(id);
        //修改指定索引位置的教师信息
        res = dao.updateTeacher(index, tea);
        sendClientData(res + "");
    }

    //根据教师id找到集合中对应的元素的索引值
    private int byIdGetIndex(String id) {
        //使用标记位思想
        int index = -1;
        //遍历集合找到id相同的元素的索引
        ArrayList<Teacher> list = dao.selectTeacher();
        for (int i = 0; i < list.size(); i++) {
            if (list.get(i) != null && id.equals(list.get(i).getSid())) {
                index = i;
            }
        }
        //返回结果
        return index;


    }

    //业务层的删除功能
    public void deleteTeacher(String id) {
        //使用标记位思想
        boolean flag = false;
        //获得同一个id在集合中的索引值
        int index = byIdGetIndex(id);
        //删除前老师数量
        int start = dao.selectTeacher().size();
        //删除指定索引位置的教师信息
        dao.deleteTeacher(index);
        //删除后老师数量
        int end = dao.selectTeacher().size();
        //判断是否添加成功
        if ((end - start) == -1) {
            flag = true;
        }
        //返回删除结果
        sendClientData(flag + "");
    }


    //获取客户端发送的数据转换成字符串数组
    public String[] receiveClientData() {
        String[] split = null;
        try {
            //创建字符缓冲输入流
            BufferedReader br = new BufferedReader(new InputStreamReader(sk.getInputStream()));
            //读取客户端发送的数据
            String data = br.readLine();
            //按照指定的格式分割字符串
            split = data.split("&");
        } catch (IOException e) {
            System.out.println("StudentService类getSocketData方法异常...............");
        } finally {
            //返回一个字符串数组
            return split;
        }
    }


    //run方法
    @Override
    public void run() {
        //接收客户端发送的数据,将其按指定格式分割成字符串数组
        String[] split = receiveClientData();
        Option option = Enum.valueOf(Option.class, split[0]);
        switch (option) {
            //判断数组第一个元素是否是login(登录)
            case LOGIN:
                //登录
                login(split[1]);
                break;
            //判断数组第二个元素是否是isExists(判断id是否存在)
            case ISEXISTS:
                isExists(split[1]);
                break;
            //判断数组第三个元素是否是addStudent(添加student对象)
            case ADD:
                addTeacher(split[1]);
                break;
            case FIND:
                selectTeacher();
                break;
            case DELETE:
                deleteTeacher(split[1]);
                break;
            case UPDATE:
                updateTeacher(split[1]);
                break;
        }
    }


    //服务端套接字对象
    Socket sk;

    //有参构造方法:设置服务端套接字
    public TeacherService(Socket sk) {
        this.sk = sk;
    }
}
